package org.jsshbroadcast.wol;

import java.net.*;
import java.util.regex.*;

public class Jwol {

    private String broadcast;
    private String mac;
    private int port;
    private byte[] macBytes;
    private byte[] bytes;

    public Jwol(String broadcast, String mac) throws Exception {
        this(broadcast, mac, 9);
    }
    
    public Jwol(String broadcast, String mac, int port) throws Exception {
        this.broadcast = validIp(broadcast);
        this.mac = mac;
        this.macBytes = getMacBytes(this.mac);
        this.port = port;

        bytes = new byte[6 + 16 * macBytes.length];
        for (int i = 0; i < 6; i++) {
            bytes[i] = (byte) 0xff;
        }
        for (int i = 6; i < bytes.length; i += macBytes.length) {
            System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
        }
    }

    public void send() throws Exception {
        InetAddress address = InetAddress.getByName(this.broadcast);
        DatagramPacket packet = new DatagramPacket(this.bytes,
                this.bytes.length, address, this.port);
        DatagramSocket socket = new DatagramSocket();
        socket.send(packet);
        socket.close();
    }

    private byte[] getMacBytes(String macStr) throws IllegalArgumentException {
        byte[] bt = new byte[6];
        String[] hex = macStr.split("(\\:|\\-)");
        if (hex.length != 6) {
            throw new IllegalArgumentException("Endereço MAC inválido (" +
                    macStr + ").");
        }
        try {
            for (int i = 0; i < 6; i++) {
                bt[i] = (byte) Integer.parseInt(hex[i], 16);
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Dígito hexadecimal inválido" +
                    " no endereço MAC (" + macStr + " ).");
        }
        return bt;
    }

    private String validIp(String ip) throws Exception {
        String regex = "(([0-1]?[0-9]{1,2}\\.)|(2[0-4][0-9]\\.)|(25[0-5]\\.))" +
                "{3}(([0-1]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(ip);
        if (!matcher.matches()) {
            throw new IllegalArgumentException("Endereço IP inválido (" +
                    ip + ").");
        }
        return ip;
    }
}